package com.ryder.petmatediarybackend.module.shop.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.ryder.petmatediarybackend.common.response.Result;
import com.ryder.petmatediarybackend.module.shop.dto.CreateAppointmentDTO;
import com.ryder.petmatediarybackend.module.shop.service.ShopAppointmentService;
import com.ryder.petmatediarybackend.module.shop.service.ShopInfoService;
import com.ryder.petmatediarybackend.module.shop.vo.AppointmentVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 描述：店铺预约管理 Controller
 *
 * @author Ryder
 * @version 1.0
 * @since 1.0
 * 更新日期: 2025-10-31
 */
@Slf4j
@Tag(name = "店铺预约管理", description = "店铺预约相关接口（需要登录）")
@RestController
@RequestMapping("/shop/appointment")
@SecurityRequirement(name = "Authorization")
@RequiredArgsConstructor
public class ShopAppointmentController {

    private final ShopAppointmentService appointmentService;
    private final ShopInfoService shopInfoService;

    @Operation(summary = "创建预约", description = "用户创建店铺预约，需要 shop:appointment:create 权限")
    @SaCheckPermission("shop:appointment:create")
    @PostMapping("/create")
    public Result<AppointmentVO> createAppointment(@Valid @RequestBody CreateAppointmentDTO dto) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("[预约管理] 用户ID={} 创建预约, shopId={}", userId, dto.getShopId());
        AppointmentVO vo = appointmentService.createAppointment(userId, dto);
        log.info("[预约管理] 用户ID={} 创建预约成功, appointmentId={}", userId, vo.getId());
        return Result.ok(vo);
    }

    @Operation(summary = "获取我的预约列表", description = "获取当前用户的预约列表，需要 shop:appointment:view 权限")
    @SaCheckPermission("shop:appointment:view")
    @GetMapping("/my-list")
    public Result<List<AppointmentVO>> getMyAppointments() {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("[预约管理] 用户ID={} 获取我的预约列表", userId);
        List<AppointmentVO> list = appointmentService.getMyAppointments(userId);
        log.info("[预约管理] 用户ID={} 获取预约列表成功, 数量={}", userId, list.size());
        return Result.ok(list);
    }

    @Operation(summary = "取消预约", description = "用户取消预约，需要 shop:appointment:cancel 权限")
    @SaCheckPermission("shop:appointment:cancel")
    @PutMapping("/cancel/{appointmentId}")
    public Result<Void> cancelAppointment(
            @PathVariable Long appointmentId,
            @RequestParam(required = false) String reason) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("[预约管理] 用户ID={} 取消预约, appointmentId={}", userId, appointmentId);
        appointmentService.cancelAppointment(userId, appointmentId, reason);
        log.info("[预约管理] 用户ID={} 取消预约成功", userId);
        return Result.ok();
    }

    @Operation(summary = "获取店铺预约列表", description = "店铺经营者获取预约列表，需要 shop:appointment:manage 权限")
    @SaCheckPermission("shop:appointment:manage")
    @GetMapping("/shop-list")
    public Result<List<AppointmentVO>> getShopAppointments() {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("[预约管理] 店铺经营者ID={} 获取预约列表", userId);
        
        // 获取店铺信息
        var shop = shopInfoService.getShopByUserId(userId);
        if (shop == null) {
            return Result.fail("店铺不存在");
        }
        
        List<AppointmentVO> list = appointmentService.getShopAppointments(shop.getId());
        log.info("[预约管理] 店铺经营者ID={} 获取预约列表成功, 数量={}", userId, list.size());
        return Result.ok(list);
    }

    @Operation(summary = "确认预约", description = "店铺经营者确认预约，需要 shop:appointment:confirm 权限")
    @SaCheckPermission("shop:appointment:confirm")
    @PutMapping("/confirm/{appointmentId}")
    public Result<Void> confirmAppointment(
            @PathVariable Long appointmentId,
            @RequestParam(required = false) String remark) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("[预约管理] 店铺经营者ID={} 确认预约, appointmentId={}", userId, appointmentId);
        
        var shop = shopInfoService.getShopByUserId(userId);
        if (shop == null) {
            return Result.fail("店铺不存在");
        }
        
        appointmentService.confirmAppointment(shop.getId(), appointmentId, remark);
        log.info("[预约管理] 店铺经营者ID={} 确认预约成功", userId);
        return Result.ok();
    }

    @Operation(summary = "拒绝预约", description = "店铺经营者拒绝预约，需要 shop:appointment:reject 权限")
    @SaCheckPermission("shop:appointment:reject")
    @PutMapping("/reject/{appointmentId}")
    public Result<Void> rejectAppointment(
            @PathVariable Long appointmentId,
            @RequestParam(required = false) String reason) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("[预约管理] 店铺经营者ID={} 拒绝预约, appointmentId={}", userId, appointmentId);
        
        var shop = shopInfoService.getShopByUserId(userId);
        if (shop == null) {
            return Result.fail("店铺不存在");
        }
        
        appointmentService.rejectAppointment(shop.getId(), appointmentId, reason);
        log.info("[预约管理] 店铺经营者ID={} 拒绝预约成功", userId);
        return Result.ok();
    }

    @Operation(summary = "完成预约", description = "店铺经营者标记预约完成，需要 shop:appointment:complete 权限")
    @SaCheckPermission("shop:appointment:complete")
    @PutMapping("/complete/{appointmentId}")
    public Result<Void> completeAppointment(@PathVariable Long appointmentId) {
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("[预约管理] 店铺经营者ID={} 完成预约, appointmentId={}", userId, appointmentId);
        
        var shop = shopInfoService.getShopByUserId(userId);
        if (shop == null) {
            return Result.fail("店铺不存在");
        }
        
        appointmentService.completeAppointment(shop.getId(), appointmentId);
        log.info("[预约管理] 店铺经营者ID={} 完成预约成功", userId);
        return Result.ok();
    }
}

